package com.eastmoney.emis.edda.infrastructure.message;

import com.eastmoney.emis.edda.config.MessageTemplateConfig;
import com.eastmoney.emis.edda.domain.entity.EddaApply;
import com.eastmoney.emis.edda.domain.entity.EddiInstruction;
import com.eastmoney.emis.edda.domain.event.EddaFailEvent;
import com.eastmoney.emis.edda.domain.event.EventPublisher;
import com.eastmoney.emis.edda.domain.valueobject.EddaApplyStatus;
import com.eastmoney.emis.edda.domain.valueobject.EddiStatus;
import com.eastmoney.emis.edda.domain.valueobject.ErrorMsg;
import com.eastmoney.emis.edda.domain.valueobject.TimeFormatter;
import com.eastmoney.emis.edda.infrastructure.account.AccountService;
import com.eastmoney.emis.edda.infrastructure.bankname.BankNameService;
import com.eastmoney.emis.logger.LoggerFactory;
import com.eastmoney.emis.utils.common.po.BaseResponse;
import com.eastmoney.emis.utils.common.utils.PinYinUtils;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.math.RoundingMode;
import java.util.HashMap;
import java.util.Map;

/**
 * @description: Description
 * @projectName: EDDA-HSBC
 * @package: com.eastmoney.emis.edda.infrastructure.message
 * @author: 汪程程
 * @date: 2022/10/18 11:13 AM
 * @version: 1.0
 */
@Service
public class MessageSenderImpl implements MessageSender {

    private static Logger log = LoggerFactory.getLogger(MessageSenderImpl.class);

    @Autowired
    private MessageSenderProvider provider;
    @Autowired
    private MessageTemplateConfig templateConfig;

    @Autowired
    private BankNameService bankNameService;

    @Autowired
    private AccountService accountService;

    @Autowired
    private EventPublisher eventPublisher;

    @Override
    public void send(EddaApply eddaApply, boolean ignore) {
        if (ignore) {
            return;
        }
        EddaApplyStatus eddaApplyStatus = EddaApplyStatus.parse(eddaApply.getStatus());
        if (eddaApplyStatus != EddaApplyStatus.SUCCESS && eddaApplyStatus != EddaApplyStatus.FAIL) {
            return;
        }
        String status = eddaApplyStatus.name().toLowerCase();
        MessageTemplateConfig.Template template = templateConfig.getEdda().get(status);
        if (template == null) {
            log.warn("edda-apply 状态异常, eid = {}, status = {}", eddaApply.getEid(), eddaApply.getStatus());
            return;
        }
        AppMessage appMessage = new AppMessage();
        appMessage.setClientId(eddaApply.getClientId());
        appMessage.setMessageCode(template.getCode());
        appMessage.setTemplateVersion(template.getVersion());

        HashMap<String, String> params = new HashMap<>();
        String bankCode = eddaApply.getBankCode();
        String bankName = bankNameService.getNameByCode(bankCode);
        params.put("bankname_hans", bankName);
        params.put("bankname_hant", PinYinUtils.convertToTraditionalChinese(bankName));
        params.put("bankname_en", bankNameService.getEngName(bankName));
        params.put("bankno", eddaApply.getBankAccount());
        params.put("accountno", accountService.getAccountCodeByClientId(eddaApply.getClientId()));

        String rejectReasonCode = eddaApply.getRejectReasonCode();
        if (!ObjectUtils.isEmpty(rejectReasonCode)) {
            ErrorMsg errorMsg = ErrorMsg.parse(rejectReasonCode);
            params.put("errormsg_hans", errorMsg.getHansMsg());
            params.put("errormsg_hant", PinYinUtils.convertToTraditionalChinese(errorMsg.getHansMsg()));
            params.put("errormsg_en", errorMsg.getEnMsg());

            eventPublisher.publish(new EddaFailEvent(eddaApply, params));
        }

        appMessage.setLanguage(eddaApply.getLanguage());
        appMessage.setTemplateParams(params);
        provider.send(appMessage);
    }


    @Override
    public void send(EddiInstruction eddiInstruction, boolean ignore) {
        if (ignore) {
            return;
        }
        EddiStatus eddiStatus = EddiStatus.parse(eddiInstruction.getStatus());
        if (eddiStatus != EddiStatus.FUND_DEPOSIT_SUCCESS && eddiStatus != EddiStatus.BANK_PROCESS_FAIL) {
            return;
        }
        String status = eddiStatus == EddiStatus.FUND_DEPOSIT_SUCCESS ? "success" : "fail";
        MessageTemplateConfig.Template template = templateConfig.getEddi().get(status);
        if (template == null) {
            log.warn("eddi-instruction 模板状态异常, eid = {}, status = {}", eddiInstruction.getEid(), eddiInstruction.getStatus());
            return;
        }
        AppMessage appMessage = new AppMessage();
        appMessage.setClientId(eddiInstruction.getClientId());
        appMessage.setMessageCode(template.getCode());
        appMessage.setTemplateVersion(template.getVersion());
        HashMap<String, String> params = new HashMap<>();

        String accountNo = accountService.getAccountCodeByClientId(eddiInstruction.getClientId());
        int length = accountNo.length();
        if (length > 4) {
            accountNo = accountNo.substring(length - 4, length);
        }
        params.put("tailNumber", accountNo);
        params.put("creditAmount", eddiInstruction.getOccurBalance().setScale(2, RoundingMode.HALF_UP).toString());
        params.put("currencyType", "HKD");
        params.put("time", TimeFormatter.YYYY_MM_DD_HH_mm_ss.format(eddiInstruction.getCreatedTime()));
        appMessage.setTemplateParams(params);
        BaseResponse<Object> response = provider.send(appMessage);
    }

    @Override
    public void sendEddaApplyFailSms(String clientId, String language, Stage stage, Map<String, String> params) {
        MessageTemplateConfig.Template template = null;
        switch (stage) {
            case APPLY:
                template = templateConfig.getSms().get(EddaApplyStatus.FAIL.generateName());
                break;
            case SET_UP:
                template = templateConfig.getSms().get(EddaApplyStatus.SET_UP_FAIL.generateName());
                break;
            default:
                break;
        }

        if (template == null) {
            log.warn("edda-sms 模板状态异常, template config = {}", templateConfig.getSms());
            return;
        }
        SmsMessage smsMessage = new SmsMessage();
        smsMessage.setClientId(clientId);
        smsMessage.setMsgNo(template.getCode());
        smsMessage.setTemplateParams(params);
        smsMessage.setLanguage(language);
        if(stage == Stage.SET_UP) {
            smsMessage.setPhoneNumber(accountService.getPhoneByClientId(clientId));
        }
        BaseResponse<Object> response = provider.send(smsMessage);
    }
}
